/*
 * Copyright 2008-2009 Nobject.org, All Rights Reserved.
 * 
 * This software is licensed under LGPL license.
 * See terms of license at gnu.org.
 * 
 * For more information,visit:
 * 
 * http://www.nobject.org
 */
package org.nobject.common.code.model.javascript;

import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

/**
 * Function Model class
 * 
 * @author bianrongjun
 * @version 1.0
 */
public class FunctionModel {

	/**
	 * Function Name
	 */
	private String functionName = null;

	/**
	 * Function Comment
	 */
	private String functionComment = null;

	/**
	 * Function Body
	 */
	private String functionBody = null;

	/**
	 * Constructor
	 */
	public FunctionModel() {

	}

	/**
	 * Constructor
	 * 
	 * @param functionName
	 */
	public FunctionModel(String functionName) {
		this.functionName = functionName;
	}

	/**
	 * Constructor
	 * 
	 * @param functionName
	 * @param functionComment
	 */
	public FunctionModel(String functionName, String functionComment) {
		this.functionComment = functionComment;
		this.functionName = functionName;
	}

	/**
	 * Function Params
	 */
	private List<ParamModel> params = new LinkedList<ParamModel>();

	/**
	 * Add Param
	 * 
	 * @param param
	 */
	public void addParam(ParamModel param) {
		if (!param.check()) {
			System.err.println("方法参数设置错误,丢弃");
		} else {
			params.add(param);
		}
	}

	/**
	 * Get Function Name
	 * 
	 * @return
	 */
	public String getFunctionName() {
		return functionName;
	}

	/**
	 * Set Function Name
	 * 
	 * @param functionName
	 */
	public void setFunctionName(String functionName) {
		this.functionName = functionName;
	}

	/**
	 * Get Function Comment
	 * 
	 * @return
	 */
	public String getFunctionComment() {
		return functionComment;
	}

	/**
	 * Set Function Comment
	 * 
	 * @param functionComment
	 */
	public void setFunctionComment(String functionComment) {
		this.functionComment = functionComment;
	}

	/**
	 * Set Function Body
	 * 
	 * @param functionBody
	 */
	public void setFunctionBody(String functionBody) {
		this.functionBody = functionBody;
	}
	
	/**
	 * addFunctionBody
	 * @param functionBody
	 */
	public void addBlock(String functionBody) {
		if(this.functionBody==null) this.functionBody="";
		this.functionBody += functionBody;
	}
	
	/**
	 * addFunctionBodyLine
	 * @param functionBody
	 */
	public void addBlockLine(String functionBody) {
		addBlock(functionBody+"\n");
	}
	
	/**
	 * addNewVariableLine
	 * @param variable
	 * @param value
	 * @param comment
	 */
	public void addNewVariableLine(String variable,String value,String comment){
		addVariable(variable, value, comment, true, true);
	}
	
	/**
	 * addVariableLine
	 * @param variable
	 * @param value
	 */
	public void addVariableLine(String variable,String value,String comment){
		addVariable(variable, value, comment, false, true);
	}
	
	private void addVariable(String variable,String value,String comment,boolean ifNew,boolean ifEmpty){
		if(value==null&&ifEmpty){
			value="null";
		}
		addBlock("\n"+variable+((value!=null)?"="+value:"")+";"+((comment!=null)?"//"+comment:"")+"\n");
	}
	
	/**
	 * addFunctionBodyLine
	 * @param functionBody
	 */
	public void addBlockLine(String functionBody,int space) {
		addBlock("\n"+functionBody+"\n");
	}
	
	/**
	 * Get Function Body
	 * 
	 * @return
	 */
	public String getFunctionBody() {
		return functionBody;
	}

	/**
	 * Get Params
	 * 
	 * @return
	 */
	public List<ParamModel> getParams() {
		return params;
	}

	/**
	 * Check
	 * 
	 * @return
	 */
	private boolean check() {
		if (this.functionName != null && !this.functionName.equals("")) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * Generate Function String
	 * 
	 * @return
	 */
	public String generateFunctionString() {
		if (!check()) {
			System.err.println("方法参数设置错误!");
			return null;
		}
		StringBuffer sb = new StringBuffer();

		// 设置注释
		sb.append("\n/**\n");
		sb.append(" * ");
		if (this.functionComment != null && !this.functionComment.equals("")) {
			sb.append(this.functionComment);
		} else {
			sb.append(this.functionName);
		}
		sb.append("\n");

		if (params.size() > 0) {
			for (Iterator iterator = params.iterator(); iterator.hasNext();) {
				ParamModel param = (ParamModel) iterator.next();
				sb.append(" * @param ");
				sb.append(param.getParamName());
				if (param.getParamComment() != null && !param.getParamComment().equals("")) {
					sb.append(" " + param.getParamComment());
				}
				if(iterator.hasNext()){
					sb.append("\n");
				}
			}
			sb.append("\n");
		}
		sb.append(" */\n");

		// 设置方法头
		sb.append("function " + this.functionName);
		sb.append("(");
		if (params.size() > 0) {
			for (Iterator iterator = params.iterator(); iterator.hasNext();) {
				ParamModel param = (ParamModel) iterator.next();
				if (!param.check()) {
					System.err.println("方法参数设置错误,丢弃");
					continue;
				}
				sb.append(param.getParamName());
				if (iterator.hasNext()) {
					sb.append(",");
				}
			}
		}
		sb.append(")");
		sb.append("{\n");

		if (this.functionBody != null && !this.functionBody.equals("")) {
			sb.append(this.functionBody);
			sb.append("\n");
		}

		sb.append("}\n");

		return sb.toString();
	}

}
